module GYLite {
//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-present, Egret Technology.
//  All rights reserved.
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Egret nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
    export var currentTarget = null;
    export var preTarget = null;
    var stageObj;
    var isPC;
    //GYLite
    export var moveDispatched:boolean;

    export var dispatch = function (type:string, bubbles:boolean, x:number, y:number, tar:any) {
        if(type == MouseEvent.ROLL_OVER && tar.isRollOver) {
            return;
        }
        if(type == MouseEvent.ROLL_OVER) {
            tar.isRollOver = true;
        }
        else if(type == MouseEvent.ROLL_OUT){//(type == egret.TouchEvent.TOUCH_END) {
            delete tar.isRollOver;
        }
        //处理鼠标手型
        if(isPC && tar.buttonModeForMouse) {
            try {
                var canvas = stageObj.$displayList.renderBuffer.surface;
                if(type == MouseEvent.ROLL_OVER) {
                    if(CommonUtil.GYIs(tar.buttonModeForMouse, String))
                        canvas.style.cursor = tar.buttonModeForMouse;
                    else
                        canvas.style.cursor = "pointer";
                }
                else if(type == MouseEvent.ROLL_OUT) {
                    canvas.style.cursor = "default";
                }
                else if(type == egret.TouchEvent.TOUCH_END) {
                    canvas.style.cursor = "default";
                }
            }
            catch(e) {
                
            }
        }
        var obj = GYSprite.player.webTouchHandler.touch.touchDownTarget;
        var touchId = null;
        var touchDown = false;
        for(var key in obj)
        {
            touchId = key;
            touchDown = true;
            break;
        }
        egret.TouchEvent.dispatchTouchEvent(tar, type, bubbles, false, x, y, touchId, touchDown);
    };

    /**
     * @language en_US
     * Enable mouse detection.
     * @version Egret 3.1.0
     * @platform Web
     */
    /**
     * @language zh_CN
     * 启用mouse检测。
     * @version Egret 3.1.0
     * @platform Web
     */
    export var enable = function (stage:egret.Stage) {
        isPC = egret.Capabilities.os == "Windows PC" || egret.Capabilities.os == "Mac OS";
        var onTouchBegin = egret.sys.TouchHandler.prototype.onTouchBegin;
        var onTouchEnd = egret.sys.TouchHandler.prototype.onTouchEnd;
        var onTouchMove = egret.sys.TouchHandler.prototype.onTouchMove;
        if(egret.Capabilities.isMobile)
        {
            egret.sys.TouchHandler.prototype.onTouchBegin = function (x:number, y:number, touchPointID:number) {
                GYSprite.stageX = x;
                GYSprite.stageY = y;
                GYSprite.addTouch(touchPointID, x, y);
                var flag:boolean = onTouchBegin.call(this, x, y, touchPointID);
                return flag;
            };
            egret.sys.TouchHandler.prototype.onTouchMove = function (x:number, y:number, touchPointID:number) {
                if(mouseMoveEnabled && !moveDispatched) {
                    var target = this.findTarget(x, y);
                    egret.TouchEvent.dispatchTouchEvent(target, MouseEvent.MOUSE_MOVE, true, true, x, y, touchPointID, true);                    
                    moveDispatched = true;
                }
                GYSprite.stageX = x;
                GYSprite.stageY = y;                
                GYSprite.addTouch(touchPointID, x, y);
                var flag:boolean = onTouchMove.call(this, x, y, touchPointID);
                moveDispatched = false;
                return flag;
            }
            return;
        }
        stageObj = stage;
        var check = function (x:number, y:number) {
            if (GYLite.preTarget && !GYLite.preTarget.$stage) {
                GYLite.dispatch(MouseEvent.MOUSE_OUT, true, x, y, GYLite.preTarget);
                GYLite.dispatch(egret.TouchEvent.TOUCH_END, false, x, y, GYLite.preTarget);
                GYLite.preTarget = null;
            }
            var result = stage.$hitTest(x, y);
            if (result != null && result != stage) {
                if (!GYLite.preTarget) {                    
                    GYLite.currentTarget = result;
                    GYLite.dispatch(MouseEvent.ROLL_OVER, true, x, y, GYLite.currentTarget);
                    GYLite.preTarget = result;
                    // dispatch(MouseEvent.MOUSE_OVER, true, x, y);
                }
                else if (result != GYLite.preTarget) {                    
                    GYLite.currentTarget = result;
                    GYLite.dispatch(MouseEvent.ROLL_OUT, true, x, y, GYLite.preTarget); //MOUSE_OUT
                    // console.log(x,y,GYSprite.stageX,GYSprite.stageY,currentTarget,result);
                    GYLite.dispatch(MouseEvent.ROLL_OVER, true, x, y, GYLite.currentTarget);
                    GYLite.preTarget = result;
                }
            }
            else {
                if (GYLite.preTarget) {                    
                    GYLite.currentTarget = null;
                    GYLite.dispatch(MouseEvent.ROLL_OUT, true, x, y, GYLite.preTarget); //MOUSE_OUT
                    // dispatch(egret.TouchEvent.TOUCH_END, false, x, y);
                    GYLite.preTarget = GYLite.currentTarget;
                    
                }
            }
        };
        var mouseX = NaN;
        var mouseY = NaN;
        
        egret.sys.TouchHandler.prototype.onTouchMove = function (x:number, y:number, touchPointID:number) {
            if(mouseMoveEnabled && !moveDispatched) {
                var target = this.findTarget(x, y);
                egret.TouchEvent.dispatchTouchEvent(target, MouseEvent.MOUSE_MOVE, true, true, x, y, touchPointID, true);
                moveDispatched = true;
            }
            GYSprite.stageX = x;
            GYSprite.stageY = y;
            GYSprite.addTouch(touchPointID, x, y);
            var flag:boolean = onTouchMove.call(this, x, y, touchPointID);            
            check(x, y);
            moveDispatched = false;
            return flag;
        };
        
        egret.sys.TouchHandler.prototype.onTouchBegin = function (x:number, y:number, touchPointID:number) {
            GYSprite.stageX = x;
            GYSprite.stageY = y;   
            GYSprite.addTouch(touchPointID, x, y);         
            var flag:boolean = onTouchBegin.call(this, x, y, touchPointID);
            check(x, y);
            return flag;
        };
        
        egret.sys.TouchHandler.prototype.onTouchEnd = function (x:number, y:number, touchPointID:number) {
            if(GYSprite.stageX != x && GYSprite.stageY != y)
            {
                if (mouseMoveEnabled && !moveDispatched) {
                    var target = this.findTarget(x, y);
                    egret.TouchEvent.dispatchTouchEvent(target, MouseEvent.MOUSE_MOVE, true, true, x, y, touchPointID, true);
                    moveDispatched = true;
                }
            }            
            GYSprite.stageX = x;
            GYSprite.stageY = y;
            GYSprite.removeTouch(touchPointID);
            var flag:boolean = onTouchEnd.call(this, x, y, touchPointID);
            check(x, y);
            moveDispatched = false;
            return flag;
        };
        // stage.addEventListener(egret.Event.ENTER_FRAME, function (){            
        //     // console.log(mouseX,mouseY,GYSprite.stageX,GYSprite.stageY);
        //     if(mouseX==mouseX && mouseY == mouseY) {
        //         // GYSprite.stageX = mouseX;
        //         // GYSprite.stageY = mouseY;                
        //         check(GYSprite.stageX,GYSprite.stageY);
        //     }
        // }, null);
    }
    
    /**
     * @language en_US
     * Set a target of buttonMode property setting is true, when the mouse rolls over the object becomes hand type.
     * @version Egret 3.1.0
     * @platform Web
     */
    /**
     * @language zh_CN
     * 设置一个对象的buttonMode属性，设置为true后，当鼠标滑过该对象会变手型。
     * @version Egret 3.1.0
     * @platform Web
     */
    export var setButtonMode = function (displayObjcet:egret.DisplayObject, buttonMode:boolean) {
        displayObjcet["buttonModeForMouse"] = buttonMode;
    }
    
    var mouseMoveEnabled = false;
    
    /**
     * @language en_US
     * Setting ON mouseMove event detection, after opening slightly impacts performance, default is not open.
     * @version Egret 3.1.0
     * @platform Web
     */
    /**
     * @language zh_CN
     * 设置开启mouseMove事件检测，开启后性能会稍有影响，默认为不开启。
     * @version Egret 3.1.0
     * @platform Web
     */
    export var setMouseMoveEnabled = function (enabled:boolean) {
        mouseMoveEnabled = enabled;
    }

    export class MouseEvent {
        /**
         * @language en_US
         * When the user mouse movements are called.
         * @version Egret 3.1.0
         * @platform Web
         */
        /**
         * @language zh_CN
         * 当用户鼠标移动时被调用。
         * @version Egret 3.1.0
         * @platform Web
         */
        public static MOUSE_MOVE:string = "mouseMove";
        
         /**
         * @language en_US
         * Called when the mouse is within the area where the object (not covered by other object).
         * @version Egret 3.1.0
         * @platform Web
         */
        /**
         * @language zh_CN
         * 当鼠标正在对象所在区域内（没有被其他对象覆盖）时调用。
         * @version Egret 3.1.0
         * @platform Web
         */
        public static MOUSE_OVER:string = "rollOver";
        
        /**
         * @language en_US
         * Called when the mouse out of the object within the Area.
         * @version Egret 3.1.0
         * @platform Web
         */
        /**
         * @language zh_CN
         * 当鼠标移出对象所在区域内时调用。
         * @version Egret 3.1.0
         * @platform Web
         */
        public static MOUSE_OUT:string = "rollOut";
        
        /**
         * @language en_US
         * When the mouse enters an object within the Area calls.
         * @version Egret 3.1.0
         * @platform Web
         */
        /**
         * @language zh_CN
         * 当鼠标进入对象所在区域内调用。
         * @version Egret 3.1.0
         * @platform Web
         */
        public static ROLL_OVER:string = "rollOver";
        
        /**
         * @language en_US
         * Called when the mouse out of the object within the Area.
         * @version Egret 3.1.0
         * @platform Web
         */
        /**
         * @language zh_CN
         * 当鼠标移出对象所在区域内时调用。
         * @version Egret 3.1.0
         * @platform Web
         */
        public static ROLL_OUT:string = "rollOut";

        
    }
}